//---------------------------------------------------------------------
// File: XmlPokeStep.cs
// 
// Summary: Provides Nant style XmlPoke functionality
//
// Copyright (c) Hammersmith & Fulham Bridge Partnership. All rights reserved.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//---------------------------------------------------------------------

using System;
using System.Xml;
using Microsoft.Services.BizTalkApplicationFramework.BizUnit;

namespace BizUnit.Extensions
{
	/// <summary>
	/// This step is modelled on the lines of the NAnt XmlPoke task
	/// The XmlPokeStep is used to update data in an XML file with values from the context
	/// This will enable the user to write tests which can use the output of one step to modify the input of another step
	/// </summary>
 	/// <code escaped="true">
	///	<TestStep assemblyPath="C:\Projects\BizUnit.Extensions.dll" typeName="BizUnit.Extensions.XmlPokeStep">
	///		<InputFileName>Name of input file</InputFileName>
	///		<XPathExpressions>
	///			<Expression>
	///				<XPath></XPath>
	///				<NewValue></NewValue>
	///			</Expression>
	///			<Expression>
	///				<XPath></XPath>
	///				<NewValue takeFromCtx="somekey"></NewValue>
	///			</Expression>
	///		</XPathExpressions>
	///	</TestStep>
	///	</code>

	public class XmlPokeStep : ITestStep
	{
		/// <summary>
		/// Execute the xmlpoke action 
		/// </summary>
		/// <param name='testConfig'>The Xml fragment containing the configuration for this test step</param>
		/// <param name='context'>The context for the test, this holds state that is passed beteen tests</param>
		public void Execute(XmlNode testConfig, Context context)
		{
			string filename = context.ReadConfigAsString( testConfig, "InputFileName" );
			XmlNodeList exprnodes  = testConfig.SelectNodes("XPathExpressions/Expression");

			// Load XML document from input file
			try
			{
				XmlDocument xDoc = new XmlDocument();
				xDoc.Load(filename);
				foreach (XmlNode node in exprnodes)
				{
					string xpathexpr = node.SelectSingleNode("XPath").InnerXml;
					string myvalue = context.ReadConfigAsString(node,"NewValue");
					context.LogInfo("Old value is " + xDoc.SelectSingleNode(xpathexpr).InnerXml);
					context.LogInfo("New value is " + myvalue);
					xDoc.SelectSingleNode(xpathexpr).InnerXml = myvalue;
				}
				xDoc.Save(filename);
			}
			catch (Exception ex)
			{
				context.LogException(ex);
			}

		}
	}
}
